package com.example.util;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import org.apache.commons.lang.time.FastDateFormat;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.Configurable;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.enhanced.TableGenerator;
import org.hibernate.type.IntegerType;
import org.hibernate.type.Type;


/**
 * hibernate jpa 主键生成方式 ,也可以尝试以下方法
 		String date = CoreDateUtils.formatDate(new Date(), "yyMMdd");
		String str = String.format("%s%03d%010d", date, 0, nextValue.longValue());
 * */


public class AssignedSequenceGenerator extends TableGenerator implements
PersistentIdentifierGenerator, Configurable  {
	private Integer INCREMENT_PARAM = 0;
	private FastDateFormat sdf;
	private Integer fmtWidth;
	@Override
	public void configure(Type arg0, Properties params, Dialect arg2)
			throws MappingException {
		super.configure(IntegerType.INSTANCE, params, arg2);//这句话相当关键啊，不然下面的都白搭
		if (params.containsKey(TableGenerator.INCREMENT_PARAM))
			INCREMENT_PARAM = new Integer(params.getProperty(TableGenerator.INCREMENT_PARAM));
		if (params.containsKey("timedate"))
			sdf = FastDateFormat.getInstance(params.getProperty("timedate"));
		if (params.containsKey(Const.Seq_fmtWidth))
			fmtWidth = new Integer(params.getProperty(Const.Seq_fmtWidth));
	}

	@Override
	public Serializable generate(SessionImplementor session, Object obj)
			throws HibernateException {      
		int seq = (Integer) super.generate(session, obj)+1+INCREMENT_PARAM;
		StringBuffer sb=new StringBuffer();
		if(sdf!=null){
			 sb.append(sdf.format(new Date()));
		}
		if (fmtWidth != null) {
			sb.append(format(seq, fmtWidth));
		} else {
			sb.append(seq);
		}
		if(sdf==null){
			sdf=FastDateFormat.getInstance("yyyyMMdd");
		}
		String dateStr=sdf.format(new Date());
		String str=String.format("%s%03d%010d", dateStr, 0,seq);
		//return sb.toString();
		return str;
		
	}


	private String format(int num, int width) {
		if (num < 0)
			return "";
		StringBuffer sb = new StringBuffer();
		String s = "" + num;
		if (s.length() < width) {
			int addNum = width - s.length();
			for (int i = 0; i < addNum; i++) {
				sb.append("0");
			}
			sb.append(s);
		} else {
			return s.substring(s.length() - width, s.length());
		}
		return sb.toString();
	}

	

}
